#include "main.h"

#pragma rodata-name (push, "LOWPRG")

static const u8 bgpal[16] = {
	0xf,
	0x30, 0xf, 0xf,
	0xf,
	0x25, 0xf, 0xf,
	0xf,
	0x15, 0xf, 0xf,
	0xf,
	0x27, 0x36, 0x17,
};

static const u8 russianmap[54] = {
	0x04 + 64, 0x05 + 64, 0x06 + 64, 0x07 + 64, 0x08 + 64, 0x09 + 64, 0x0a + 64, 0x0b +
	64, 0x0c + 64, 0x0d + 64, 0x0e + 64, 0x0f + 64, 0x10 + 64, 0x11 + 64, 0x12 + 64,
	0x13 + 64, 0x14 + 64, 0x15 + 64,
	0x19 + 64, 0x1a + 64, 0x1b + 64, 0x1c + 64, 0x1d + 64, 0x1e + 64, 0x1f + 64, 0x20 +
	64, 0x21 + 64, 0x22 + 64, 0x23 + 64, 0x24 + 64, 0x25 + 64, 0x26 + 64, 0x27 + 64,
	0x28 + 64, 0x29 + 64, 0x2a + 64,
	0x2f + 64, 0x30 + 64, 0x31 + 64, 0x32 + 64, 0x33 + 64, 0x34 + 64, 0x35 + 64, 0x36 +
	64, 0x37 + 64, 0x38 + 64, 0x39 + 64, 0x3a + 64, 0x3b + 64, 0x3c + 64, 0x3d + 64,
	0x3e + 64, 0x3f + 64, 0x03 + 64,
};

static const u8 bulletmap[12] = {
	0x00 + 64, 0x01 + 64, 0x02 + 64, 0,
	0x16 + 64, 0x17 + 64, 0x18 + 64, 0,
	0x2b + 64, 0x2c + 64, 0x2d + 64, 0x2e + 64,
};

static const u8 roulettemap[60] = {
	0x00 + 128, 0x01 + 128, 0x02 + 128, 0x03 + 128, 0x03 + 128, 0x04 + 128, 0x05 + 128,
	0x04 + 128, 0x06 + 128, 0x07 + 128, 0x04 + 128, 0x00 + 128, 0x08 + 128, 0x09 + 128,
	0x0a + 128, 0x0b + 128, 0x0c + 128, 0x0d + 128, 0x0e + 128, 0x0f + 128,
	0x10 + 128, 0x11 + 128, 0x12 + 128, 0x03 + 128, 0x03 + 128, 0x13 + 128, 0x14 + 128,
	0x13 + 128, 0x15 + 128, 0x16 + 128, 0x13 + 128, 0x17 + 128, 0x18 + 128, 0x19 + 128,
	0x16 + 128, 0x03 + 128, 0x1a + 128, 0x1b + 128, 0x1c + 128, 0x1d + 128,
	0x1e + 128, 0x1f + 128, 0x20 + 128, 0x03 + 128, 0x03 + 128, 0x21 + 128, 0x22 + 128,
	0x23 + 128, 0x24 + 128, 0x25 + 128, 0x26 + 128, 0x27 + 128, 0x28 + 128, 0x29 + 128,
	0x2a + 128, 0x03 + 128, 0x2b + 128, 0x2c + 128, 0x2d + 128, 0x2e + 128,
};

#pragma rodata-name (pop)

#pragma code-name (push, "LOWPRG")

void title() {

	static u16 secs;
	static u8 ctrl, choice, prevctrl, x, y, i;
	static u8 beenhere;

	gamemode = G_DEMO;
	choice = 0;
	prevctrl = 0;

	oam_clear();
	oam_meta_spr(9 * 8 + 4, 8 * 8 - 1, 0, smallchamber_metasprite);

	vram_adr(NAMETABLE_A);
	vram_fill(0, 1024);

	// BG palettes: white text, pink text, red text, ammo
	// Sprite pal 0 is the chamber

	pal_bg(bgpal);

	pal_col(17, 0x30);
	pal_col(18, 0x10);
	pal_col(19, 0x0);

	bankswitch(3, CHR_BULLETLOGO);
	bankswitch(4, CHR_ROULETTE);

	// Russian
	i = 0;
	for (y = 0; y < 3; y++) {
		for (x = 0; x < 18; x++) {
			vram_adr(NTADR_A(x + 4, y + 4));
			vram_put(russianmap[i++]);
			pal_nt(x + 4, y + 4, 2);
		}
	}

	// Bullet
	i = 0;
	for (y = 0; y < 3; y++) {
		for (x = 0; x < 4; x++) {
			vram_adr(NTADR_A(x + 22, y + 4));
			vram_put(bulletmap[i++]);
			pal_nt(x + 22, y + 4, 3);
		}
	}

	// Roulette
	i = 0;
	for (y = 0; y < 3; y++) {
		for (x = 0; x < 20; x++) {
			vram_adr(NTADR_A(x + 7, y + 8));
			vram_put(roulettemap[i++]);
		}
	}

	vram_adr(NTADR_A(8, 14));
	str("1 PLAYER GAME A");

	vram_adr(NTADR_A(8, 16));
	str("1 PLAYER GAME B");

	vram_adr(NTADR_A(8, 18));
	str("2 PLAYER GAME A");

	vram_adr(NTADR_A(8, 20));
	str("2 PLAYER GAME B");

	fmtscore(topscore[0]);
	vram_adr(NTADR_A(11, 23));
	str("TOP-");
	str(scorebuf);

	for (i = 11; i < 30; i += 2)
		pal_nt(i, 23, 1);

	vram_adr(NTADR_A(7, 27));
	str("@ 2016 INTENDON CO.");

	if (zapper) {
		vram_adr(NTADR_A(8, 25));
		str("ZAPPER DETECTED");
	}

	ppu_on_all();

	if (beenhere % 4 == 0) {
		music_play(MUSIC_TITLE);
		musicctr = 0;
		musiclimit = 780;

		beenhere = 0;
	}

	zappershot = 0;

	for (secs = 0; secs < 300; ++secs) {
		ctrl = joy_read(0);

		if (zapper && zappershot) {
			shotscreen();
		}

		musicctr++;
		if (musiclimit && musicctr > musiclimit) {
			music_stop();
			musiclimit = 0;
		}

		if ((ctrl & (KEY_A | KEY_START)) ||
			(zapper && zappershot && !zapperdark)) {
			gamemode = choice + 1;
			music_play(MUSIC_GAME_START);

			delay(220);
			break;
		}
		if (ctrl & KEY_UP && !(prevctrl & KEY_UP)) {
			if (choice)
				choice--;
			else
				choice = 3;

			secs = 0;
		}
		if ((ctrl & KEY_DOWN && !(prevctrl & KEY_DOWN)) ||
			(zapper && zappershot && zapperdark)) {
			choice++;
			choice %= 4;

			secs = 0;

			if (zapper && zappershot) {
				sfx_play(SFX_LIGHTGUN, 0);
				delay(7);
				zappertmp = 0;
				zappershot = 0;
			}
		}

		// Update pointer
		addr = NTADR_A(6, 14);
		bgbuf[0] = MSB(addr);
		bgbuf[1] = LSB(addr);
		bgbuf[2] = choice == 0 ? '/' - ' ' : 0;

		addr = NTADR_A(6, 16);
		bgbuf[3] = MSB(addr);
		bgbuf[4] = LSB(addr);
		bgbuf[5] = choice == 1 ? '/' - ' ' : 0;

		addr = NTADR_A(6, 18);
		bgbuf[6] = MSB(addr);
		bgbuf[7] = LSB(addr);
		bgbuf[8] = choice == 2 ? '/' - ' ' : 0;

		addr = NTADR_A(6, 20);
		bgbuf[9] = MSB(addr);
		bgbuf[10] = LSB(addr);
		bgbuf[11] = choice == 3 ? '/' - ' ' : 0;

		// Update scores
		fmtscore(topscore[choice]);
		addr = NTADR_A(15, 23);

		bgbuf[12] = MSB(addr) | NT_UPD_HORZ;
		bgbuf[13] = LSB(addr);
		bgbuf[14] = 5;

		bgbuf[15] = scorebuf[0] - ' ';
		bgbuf[16] = scorebuf[1] - ' ';
		bgbuf[17] = scorebuf[2] - ' ';
		bgbuf[18] = scorebuf[3] - ' ';
		bgbuf[19] = scorebuf[4] - ' ';

		bgbuf[20] = NT_UPD_EOF;

		// Reset scores?
		#define SECRET (KEY_LEFT | KEY_B | KEY_SELECT)
		if ((ctrl & SECRET) == SECRET) {
			ctrl = 0;
			while (1) {
				addr = NTADR_A(4, 12);

				if (ctrl & (KEY_UP | KEY_DOWN | KEY_RIGHT)) {

					memfill(bgbuf, 0, 26);

					bgbuf[0] = MSB(addr) | NT_UPD_HORZ;
					bgbuf[1] = LSB(addr);
					bgbuf[2] = 23;

					bgbuf[26] = NT_UPD_EOF;

					ppu_wait_nmi();

					if (ctrl & KEY_RIGHT)
						resetscores();
					ctrl = 0;

					break;
				}

				addr = NTADR_A(4, 12);
				bgbuf[0] = MSB(addr) | NT_UPD_HORZ;
				bgbuf[1] = LSB(addr);
				bgbuf[2] = 23;

				bgbuf[3] = 'P' - ' ';
				bgbuf[4] = 'R' - ' ';
				bgbuf[5] = 'E' - ' ';
				bgbuf[6] = 'S' - ' ';
				bgbuf[7] = 'S' - ' ';

				bgbuf[8] = 0;

				bgbuf[9] = '>' - ' ';

				bgbuf[10] = 0;

				bgbuf[11] = 'T' - ' ';
				bgbuf[12] = 'O' - ' ';

				bgbuf[13] = 0;

				bgbuf[14] = 'E' - ' ';
				bgbuf[15] = 'R' - ' ';
				bgbuf[16] = 'A' - ' ';
				bgbuf[17] = 'S' - ' ';
				bgbuf[18] = 'E' - ' ';

				bgbuf[19] = 0;

				bgbuf[20] = 'S' - ' ';
				bgbuf[21] = 'C' - ' ';
				bgbuf[22] = 'O' - ' ';
				bgbuf[23] = 'R' - ' ';
				bgbuf[24] = 'E' - ' ';
				bgbuf[25] = 'S' - ' ';

				bgbuf[26] = NT_UPD_EOF;

				ppu_wait_nmi();
				prevctrl = ctrl;
				ctrl = joy_read(0);
			}
		}

		if (zapper)
			ppu_wait_zapper();
		else
			ppu_wait_nmi();
		prevctrl = ctrl;

		rand8();
	}

	if (gamemode != G_DEMO)
		music_stop();
	ppu_off();
	oam_clear();
	bgbuf[0] = NT_UPD_EOF;

	beenhere++;
}

#pragma code-name (pop)
